package cn.com.shopec.erp.system.common;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.codehaus.jackson.map.ObjectMapper;


public class StringUtils extends org.springframework.util.StringUtils{
	private static Log log = LogFactory.getLog(StringUtils.class);
	
	/**
	 * 私有构造函数，不允许本类生成实例 
	 */
	private StringUtils(){
		
	}
	
	/**
	 * 得到一个非null的字符串（如果传入参数为null时，得到一个0长度的空字符串）
	 * @param obj
	 * @return
	 */
	public static String getNotNullString(Object obj) {
		if(obj == null){
			return "";
		}else{
			return obj instanceof String ? (String)obj : obj.toString();
		}
	}
	
	/**
	 * 根据分隔符，将字符串分割为List
	 * @param s
	 * @param separator
	 * @param decode
	 * @return
	 */
	public static List<String> splitStrToList(String s, String separator,
			boolean decode) {
		List<String> lst = new ArrayList<String>(2);
		StringBuilder sb = new StringBuilder();
		int pos = 0, end = s.length();
		while (pos < end) {
			if (s.startsWith(separator, pos)) {
				if (sb.length() > 0) {
					lst.add(sb.toString());
					sb = new StringBuilder();
				}
				pos += separator.length();
				continue;
			}

			char ch = s.charAt(pos++);
			if (ch == '\\') {
				if (!decode)
					sb.append(ch);
				if (pos >= end)
					break; // ERROR, or let it go?
				ch = s.charAt(pos++);
				if (decode) {
					switch (ch) {
					case 'n':
						ch = '\n';
						break;
					case 't':
						ch = '\t';
						break;
					case 'r':
						ch = '\r';
						break;
					case 'b':
						ch = '\b';
						break;
					case 'f':
						ch = '\f';
						break;
					}
				}
			}

			sb.append(ch);
		}

		if (sb.length() > 0) {
			lst.add(sb.toString());
		}

		return lst;
	}

	/**
	 * 按空格将字符串分割为List
	 * @param s
	 * @param decode
	 * @return
	 */
	public static List<String> splitWSToList(String s, boolean decode) {
		List<String> lst = new ArrayList<String>(2);
		StringBuilder sb = new StringBuilder();
		int pos = 0, end = s.length();
		while (pos < end) {
			char ch = s.charAt(pos++);
			if (Character.isWhitespace(ch)) {
				if (sb.length() > 0) {
					lst.add(sb.toString());
					sb = new StringBuilder();
				}
				continue;
			}

			if (ch == '\\') {
				if (!decode)
					sb.append(ch);
				if (pos >= end)
					break; // ERROR, or let it go?
				ch = s.charAt(pos++);
				if (decode) {
					switch (ch) {
					case 'n':
						ch = '\n';
						break;
					case 't':
						ch = '\t';
						break;
					case 'r':
						ch = '\r';
						break;
					case 'b':
						ch = '\b';
						break;
					case 'f':
						ch = '\f';
						break;
					}
				}
			}

			sb.append(ch);
		}

		if (sb.length() > 0) {
			lst.add(sb.toString());
		}

		return lst;
	}

	/**
	 * 移除字符串中的所有空格（不论在什么位置，包括空格，制表符，换行符都会被移除）
	 * @param s
	 * @return
	 */
	public static String removeAllWhiteSpace(String s){
		if(s == null || s.length() == 0) {
			return s;
		}
		return s.replaceAll("\\s", "");
	}
	
	/**
	 * 将多个连续重复字符，缩减为一个。如aabcccbbd会被处理为abcbd
	 * @param s
	 * @return
	 */
	public static String cutContinuousDuplicateCharsToOne(String s) {
		if(s == null || s.length() == 0) {
			return s;
		}
		return s.replaceAll("(.)\\1+", "$1");
	}
	
	/**
	 * 将多个连续重复的空白字符，缩减为一个空格。如a   b			c d会被处理为a b c d
	 * @param s
	 * @return
	 */
	public static String cutContinuousDuplicateWhitespacesToOne(String s) {
		if(s == null || s.length() == 0) {
			return s;
		}
		return s.replaceAll("\\s+", " ");
	}
	
	/**
	 * 对象转为json格式字符串
	 * @param o
	 * @return
	 */
	public static String convertObjToJsonStr(Object o) {
		if(o == null)
			return null;
		String s = "";
		ObjectMapper m = new ObjectMapper();
		try {
			s = m.writeValueAsString(o);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
		}
		return s;
	}
	
	/**
	 * json格式的字符串，转为对象
	 * @param s
	 * @param clazz
	 * @return
	 */
	public static Object parseJsonStrToObject(String s,Class<?> clazz) {
		if(s == null) 
			return null;
		Object o = null;
		ObjectMapper m = new ObjectMapper();
		try {
			o = m.readValue(s, clazz);
		} catch (Exception e) {
			log.error("s="+s);
			log.error(e.getMessage(), e);
		}
		return o;
	}
	
	/**
	 * 去掉字符串中的html标记（以<开头，>结尾的子串将会被删除）
	 * @param s
	 * @return
	 */
	public static String removeHTMLMarks(String s) {
		String r = "";
		if(s != null) {
			r = s.replaceAll("<(.*?)>", "");
		}
		return r;
	}

	/**
	 * 字符串中，是否包含汉字（全角字符不算汉字）
	 * @param s
	 * @return
	 */
	public static boolean isIncludeChineseCharacter(String s) {
		return s != null && s.length() > 0 && java.util.regex.Pattern.matches(".*[\u4E00-\u9FA5].*", s);
	}

	/**
	 * 将字符串转为整数，如果字符串为null、空串或非正确格式的字符串，则返回一个默认值0。
	 * @param str 待转换的字符串
	 * @return
	 */
	public static int convertStringToInt(String str){
		return convertStringToInt(str, 0);
	}
	
	/**
	 * 将字符串转为整数，如果字符串为null、空串或非正确格式的字符串，则返回一个默认的整数值，默认值由defaultValue参数指定。
	 * @param str 待转换的字符串
	 * @param defaultValue 默认值
	 * @return
	 */
	public static int convertStringToInt(String str,int defaultValue) {
		int value = defaultValue;
		try{
			value = Integer.parseInt(str);
		}catch(NullPointerException npe) {
			log.error(npe);
		}catch(NumberFormatException nfe) {
			log.error(nfe);
		}
		return value;
	}

	/**
	 * 将字符串转为长整数，如果字符串为null、空串或非正确格式的字符串，则返回一个默认值0。
	 * @param str 待转换的字符串
	 * @return
	 */
	public static long convertStringToLong(String str) {
		return convertStringToLong(str, 0L);
	}
	
	/**
	 * 将字符串转为长整数，如果字符串为null、空串或非正确格式的字符串，则返回一个默认的整数值，默认值由defaultValue参数指定。
	 * @param str 待转换的字符串
	 * @param defaultValue 默认值
	 * @return
	 */
	public static long convertStringToLong(String str,long defaultValue) {
		long value = defaultValue;
		try{
			value = Long.parseLong(str);
		}catch(NullPointerException npe) {
			log.error(npe);
		}catch(NumberFormatException nfe) {
			log.error(nfe);
		}
		return value;
	}
	
	/**
	 * 将字符串转为double型浮点数，如果字符串为null、空串或非正确格式的字符串，则返回一个默认值0.0。
	 * @param str 待转换的字符串
	 * @return
	 */
	public static double convertStringToDouble(String str) {
		return convertStringToDouble(str, 0.0D);
	}
	
	/**
	 * 将字符串转为double型浮点数，如果字符串为null、空串或非正确格式的字符串，则返回一个默认的double值，默认值由defaultValue参数指定。
	 * @param str 待转换的字符串
	 * @param defaultValue 默认值
	 * @return
	 */
	public static double convertStringToDouble(String str,double defaultValue) {
		double value = defaultValue;
		try{
			value = Double.parseDouble(str);
		}catch(NullPointerException npe) {
			log.error(npe);
		}catch(NumberFormatException nfe) {
			log.error(nfe);
		}
		return value;
	}
	
	/**
	 * 使用逗号分隔符，将一个字符串切割为整型数的数组。例如字符串 "1,2,3,4"，用逗号分割后，得到一个[1,2,3,4]的整型数组。
	 * 如果字符串分割后，有非法字符时，则会被转为0。
	 * @param str
	 * @return
	 */
	public static int[] splitStringToIntArr(String str) {
		return splitStringToIntArr(str, "\\,");
	}
	
	/**
	 * 基于分隔符（支持正则），将一个字符串切割为整型数的数组。例如字符串 "1,2,3,4"，用逗号分割后，得到一个[1,2,3,4]的整型数组。
	 * 如果字符串分割后，有非法字符时，则会被转为0。
	 * @param str
	 * @param regex
	 * @return
	 */
	public static int[] splitStringToIntArr(String str,String regex) {
		int[] intArr = null;
		if(hasText(str)){
			String[] strArr = str.split(regex);
			intArr = new int[strArr.length];
			for(int i = 0 ; i < strArr.length ; i++) {
				intArr[i] = convertStringToInt(strArr[i]);
			}
		}
		intArr = intArr == null ? new int[0] : intArr;
		return intArr;
	}
	
	/**
	 * 基于逗号，将一个字符串，分割成数组，并仅在数组中去除重复的值。
	 * 例如： 输入"a,b,c,a,b,d" 这个字符串，并用逗号分割，则可以得到一个数组 [a,b,c,d]（a,b都有重复的，但被去掉了）
	 * @param str
	 * @return
	 */
	public static String[] splitStringAndRemoveDuplication(String str) {
		return splitStringAndRemoveDuplication(str, "\\,");
	}
	
	/**
	 * 基于分隔符（支持正则），将一个字符串，分割成数组，并仅在数组中去除重复的值。
	 * 例如： 输入"a,b,c,a,b,d" 这个字符串，并用逗号分割，则可以得到一个数组 [a,b,c,d]（a,b都有重复的，但被去掉了）
	 * @param str
	 * @param regex
	 * @return
	 */
	public static String[] splitStringAndRemoveDuplication(String str,String regex) {
		String[] res = new String[]{};
		if(str == null || regex == null){
			return res;
		}
		String[] arr = str.split(regex);
		if(arr.length > 0){
			Set<String> set = new LinkedHashSet<String>(arr.length); //利用Set来实现去重
			for(String s:arr){
				set.add(s);
			}
			
			res = set.toArray(res);
		}
		return res;
	}
	
	
}
